__author__ = 'shawhen'

import ctypes

from ...cstd import stddef as m_stddef

from . import libc as m_libc

STDIN_FILENO = 0
STDOUT_FILENO = 1
STDERR_FILENO = 2

def fork():
    """
    :return -1 for failed; 0 for child; + for parent
    """
    return m_libc.libc_dll.fork()

def pipe():
    """
    :return (read_of_pipe/None, write_of_pipe/None)
    """
    pipes = (ctypes.c_int * 2)()
    result = m_libc.libc_dll.pipe(pipes)
    if result != 0:
        return None, None
    else:
        return pipes[0], pipes[1]


def write(fd, buf):
    """
    :return bytes_written; -1 for failed; and errno
    """
    return m_libc.libc_dll.write(fd, buf, len(buf))


def read(fd, bytes2read):
    """
    :return (0/-1, read buf/None)
    """
    buf = ctypes.create_string_buffer(bytes2read)
    read_bytes = m_libc.libc_dll.read(fd, buf, bytes2read)
    if read_bytes < 0:
        return read_bytes, None
    return 0, buf.value[:read_bytes]


def close(fd):
    """
    :return -1 for failed; and errno
    """
    return m_libc.libc_dll.close(fd)

def dup2(oldfd, newfd):
    """
    :return -1 for failed
    """
    return m_libc.libc_dll.dup2(oldfd, newfd)


def chdir(path):
    """
    :param path python-str
    :return -1 for failed; and errno
    """
    return m_libc.libc_dll.chdir(path.encode())


def execvp(file, argv):
    """
    :file path of the file(if no slash then search in PATH)
    :param argv python-str-list
    :return < 0 for failed
    """
    argv_to_api = []
    argv_to_api.append(file.encode())
    for argv_i in argv:
        argv_to_api.append(argv_i.encode())
    argv_to_api.append(0)

    argv_to_api_c = (ctypes.c_char_p*len(argv_to_api))(*argv_to_api)
    return m_libc.libc_dll.execvp(file.encode(), argv_to_api_c)